<script setup lang="ts">
import {onMounted, ref, watch, onUnmounted} from "vue";
import SvgIcon from "../Tool/svg-icon.vue";
import {userStore} from "../../store";
import {delete_file, LeiToolsNotebookDatabase, read_file, write_file, NotebookInterface} from '../../lib/database.ts'
import Vditor from "vditor";
import {open, save} from '@tauri-apps/plugin-dialog'
import {stat} from "@tauri-apps/plugin-fs";
import {ElMessage} from "element-plus";

const store = userStore()
const database = new LeiToolsNotebookDatabase("./sqlite.db")
let editor = ref<Vditor>();
const content = ref<string>('## Hello World')
// 文件全部的数据
const fileList = ref<NotebookInterface[]>([])
// 当前访问的文件所对应的全部内容
const current = ref<NotebookInterface>()
// 当前访问文件的名称
const currentTitle = ref('')

async function filter_file(filter: string = '') {
    return await database.query(filter)
}

onMounted(async () => {
    await database.open()
    await database.createTable()
    // 查询所有的表数据
    fileList.value = (await database.query()) as NotebookInterface[]
    if (fileList.value.length !== 0) {
        current.value = fileList.value[0]
        currentTitle.value = current.value.title
    }

    if (editor.value === undefined) {
        editor.value = new Vditor('vditor', {
            mode: 'ir',
            height: '100%',
            toolbar: [],
            typewriterMode: true,
            cache: {
                enable: false,
            },
            after: async () => {
                if (current.value !== undefined) {
                    const path = current.value.directory + '\\' + current.value.title + '.md'
                    content.value = await read_file(path)
                }
                (editor.value as Vditor).setValue(content.value);
                editor.value?.setTheme(
                    store.isDarkMode ? 'dark' : 'classic',
                    store.isDarkMode ? 'dark' : 'light',
                    store.isDarkMode ? 'solarized-dark256' : 'solarized-light')
            }
        })
    }
})

onUnmounted(async () => {
    await database.close()
    console.log('数据库已关闭')
})

watch(() => [store.isDarkMode], () => {
    editor.value?.setTheme(
        store.isDarkMode ? 'dark' : 'classic',
        store.isDarkMode ? 'dark' : 'light',
        store.isDarkMode ? 'solarized-dark256' : 'solarized-light')
}, {deep: true});

const handleClick = async (label: string) => {
    if (label === 'add') {
        // 新建文件
        content.value = ''
        currentTitle.value = ''
        editor.value.setValue(content.value)
    }
    else if (label === 'upload') {
        // 上传文件
        const filepath = await open({
            multiple: false, directory: false,
            filters: [{
                name: 'Markdown',
                extensions: ['md']
            }]
        })
        if (filepath === null) {
            ElMessage({
                type: 'error',
                message: '当前未选择上传文件，上传失败'
            })
            return
        }
        const pathArr = filepath.split('\\')
        const filter = `title='${pathArr.reverse()[0].split('.')[0]}' and directory='${pathArr.reverse().slice(0, pathArr.length - 1).join('\\')}'`
        // 如果当前文件存在
        const files = await filter_file(filter)
        if (files.length > 0) {
            ElMessage({
                type: 'warning',
                message: '当前文件已存在，上传失败'
            })
            return
        }
        // 获取对应文件的基础信息
        const fileInfo = await stat(filepath)
        current.value = {
            title: pathArr.reverse()[0].split('.')[0],
            directory: pathArr.reverse().slice(0, pathArr.length - 1).join('\\'),
            createTime: fileInfo.birthtime.toLocaleString(),
            collect: 0
        }
        // 读取文件内容
        content.value = await read_file(filepath)
        // 将文件内容放置在编辑器中
        editor.value.setValue(content.value)
        // 将文件信息写入数据库
        await database.insert(current.value)
        // 更新文件列表与更新对应current的数据
        fileList.value = (await database.query()) as NotebookInterface[]
        current.value = fileList.value.filter(item => item.title === current.value.title &&
            item.directory === current.value.directory)[0]
        currentTitle.value = current.value.title
        ElMessage({
            type: 'success',
            message: '上传成功'
        })

    }
    else if (label === 'save') {
        // 保存文件
        let filepath = ''
        // 判断是新建的文件还是已经存在的文件
        if (currentTitle.value === '') {
            // 新建的文件
            filepath = await save({
                filters: [{
                    name: 'Markdown',
                    extensions: ['md']
                }],
            })
            if (filepath === null) {
                ElMessage({
                    type: 'error',
                    message: '当前未选择保存路径，保存失败'
                })
                return
            }
        }
        else {
            // 已经存在的文件
            filepath = current.value.directory + '\\' + current.value.title + '.md'
        }
        // 写入文件
        content.value = editor.value.getValue()
        await write_file(filepath, content.value)

        if (currentTitle.value === '') {
            // 新建的文件，需要写入数据库
            const fileInfo = await stat(filepath)
            const pathArr = filepath.split('\\')
            current.value = {
                title: pathArr.reverse()[0].split('.')[0],
                directory: pathArr.reverse().slice(0, pathArr.length - 1).join('\\'),
                createTime: fileInfo.birthtime.toLocaleString(),
                collect: 0
            }
            const files = await filter_file(`title='${current.value.title}' and directory='${current.value.directory}'`)
            if (files.length > 0) {
                // 已经存在该文件，更新文件
                current.value.id = (files[0] as NotebookInterface).id
                currentTitle.value = current.value.title
            } else {
                // 不存在该文件，插入文件
                await database.insert(current.value)
                // 更新文件列表与更新对应current的数据
                fileList.value = (await database.query()) as NotebookInterface[]
                // 从fileList中过滤出current的内容
                current.value = fileList.value.filter(item => item.title === current.value.title &&
                    item.directory === current.value.directory)[0]
                currentTitle.value = current.value.title
            }
        }
        ElMessage({
            type: 'success',
            message: '保存成功'
        })
    }
    else if (label === 'delete') {
        // 删除文件
        if (currentTitle.value === '') {
            ElMessage({
                type: 'error',
                message: '当前未选择删除文件，删除失败'
            })
            return
        }
        // 删除文件
        const filepath = current.value.directory + '\\' + current.value.title + '.md'
        await delete_file(filepath)
        // 删除数据库中的文件
        const filter = `id = ${current.value.id}`
        await database.delete(filter)
        // 更新文件列表与更新对应current的数据
        fileList.value = (await database.query()) as NotebookInterface[]
        current.value = fileList.value[0]
        currentTitle.value = current.value.title
        ElMessage({
            type:'success',
            message: '删除成功'
        })
        // 更新编辑器中的内容
        content.value = await read_file(current.value.directory + '\\' + current.value.title + '.md')
        editor.value.setValue(content.value)
    }
    else if (label === 'download') {
        // 下载文件，转换成html文件
        if (currentTitle.value === '') {
            ElMessage({
                type: 'error',
                message: '当前未选择下载文件，下载失败'
            })
            return
        }
        // 导出html文件
        const filepath = await save({
            defaultPath: current.value.title + '.html',
            filters: [{
                name: 'HTML',
                extensions: ['html']
            }],
        })
        await write_file(filepath, editor.value.getHTML())
        ElMessage({
            type:'success',
            message: '下载成功'
        })
    }
    else if (label === 'collect') {
        // 收藏文件
        if (currentTitle.value === '') {
            ElMessage({
                type: 'error',
                message: '当前未选择收藏文件，收藏失败'
            })
            return
        }
        // 更新数据库中的文件
        const filter = `id = ${current.value.id}`
        current.value.collect = current.value.collect === 1 ? 0 : 1
        await database.update(current.value, filter)
        // 提示收藏成功
        ElMessage({
            type:'success',
            message: current.value.collect === 1? '收藏成功' : '取消收藏成功'
        })
    }
}

const handleMenuClick = async (val: any) => {
    currentTitle.value = val.index
    current.value = fileList.value.filter(item => item.title === currentTitle.value)[0]
    content.value = await read_file(current.value.directory + '\\' + current.value.title + '.md')
    editor.value?.setValue(content.value)
}

const optionList = [
    {
        icon: 'add',
        label: '新建笔记',
    }, {
        icon: 'collect',
        label: '收藏笔记',
    }, {
        icon: 'save',
        label: '保存笔记',
    }, {
        icon: 'delete',
        label: '删除笔记',
    }, {
        icon: 'upload',
        label: '上传笔记',
    }, {
        icon: 'download',
        label: '下载笔记',
    }
]

</script>

<template>
    <el-row :gutter="6" style="width: 100%; height: 100%">
        <el-col :span="6" style="height: 100%">
            <el-card style="height: 100%" body-style="padding: 5px">
                <template #header>
                    <el-text>笔记列表</el-text>
                </template>
                <el-menu
                    :default-active="currentTitle"
                >
                    <el-menu-item v-for="file in fileList" :index="file.title" @click="handleMenuClick">
                        <el-icon :size="25">
                            <svg-icon v-if="file.collect === 1" name="collected" width="25px" height="25px"/>
                            <svg-icon v-if="file.collect === 0" name="collect" width="25px" height="25px"/>
                        </el-icon>
                        <template #title>{{ file.title }}</template>
                    </el-menu-item>
                </el-menu>
            </el-card>
        </el-col>
        <el-col :span="18" style="height: 100%">
            <el-card style="height: 100%" body-style="height: calc(100% - 90px)">
                <template #header>
                    <div style="width: 100%; display: flex; justify-content: flex-end">
                        <el-tooltip
                            effect="dark"
                            :content="item.label"
                            placement="top"
                            v-for="item in optionList"
                        >
                            <el-button type="info" circle @click="handleClick(item.icon)">
                                <el-icon :size="25">
                                    <svg-icon :name="item.icon" width="20px" height="20px"></svg-icon>
                                </el-icon>
                            </el-button>
                        </el-tooltip>
                    </div>
                </template>
                <div id="vditor" style="height: 100%;"/>
            </el-card>
        </el-col>
    </el-row>
</template>

<style scoped lang="css">
:deep(.vditor-ir pre.vditor-reset:after) {
    height: 20px;
}

:deep(.vditor-toolbar) {
    border: none;
}

#vditor {
    border: none;
}

:deep(.vditor-reset) {
    background-color: var(--el-fill-color-blank, var(--el-fill-color-blank));
    border: none;
    box-sizing: border-box;
    border-radius: var(--el-border-radius-base, var(--el-border-radius-base)) !important;
    box-shadow: 0 0 0 1px var(--el-border-color, var(--el-border-color)) inset !important;
}

:deep(.vditor-reset:hover) {
    box-shadow: 0 0 0 1px var(--el-border-color-hover) inset !important;
}

:deep(.vditor-reset:focus) {
    box-shadow: 0 0 0 1px var(--el-color-primary) inset !important;
}

:deep(.vditor--dark) {
    --panel-background-color: var(--el-card-bg-color);
}
</style>